/*
 * errormsg.c - functions used in all phases of the compiler to give
 *              error messages about the Tiger program.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "util.h"
#include "errormsg.h"

bool anyErrors = FALSE;

static string fileName = "";

static int lineNum = 1;

int EM_tokPos = 0;

extern FILE *yyin;

typedef struct intList
{
	int i;
	struct intList *rest;
}*IntList;

static IntList intList(int i, IntList rest)
{
	IntList l = checked_malloc(sizeof *l);
	l->i = i;
	l->rest = rest;
	return l;
}

static IntList linePos = NULL;

void EM_newline(void)
{
	lineNum++;
	linePos = intList(EM_tokPos, linePos);
}

void EM_error(int pos, char *message, ...)
{
	va_list ap;
	IntList lines = linePos;
	int num = lineNum;

	anyErrors = TRUE;
	while (lines && lines->i >= pos)
	{
		lines = lines->rest;
		num--;
	}

	if (fileName)
		fprintf(stderr,"%s:",fileName);
	if (lines)
		fprintf(stderr,"%d.%d: ", num, pos-lines->i);
	va_start(ap, message);
	vfprintf(stderr, message, ap);
	va_end(ap);
	fprintf(stderr,"\n");

}

void EM_reset(string fname)
{
	anyErrors = FALSE;
	fileName = fname;
	lineNum = 1;
	linePos = intList(0, NULL );
	yyin = fopen(fname, "r");
	if (!yyin)
	{
		EM_error(0, "cannot open");
		exit(1);
	}
}
